home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / gnome-orca / orca / outloud.py < prev    next >
Encoding:
Python Source  |  2009-04-13  |  10.8 KB  |  415 lines

  1. # Orca
  2. #
  3. # Copyright 2005-2008 Google Inc.
  4. #
  5. # This library is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Library General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 2 of the License, or (at your option) any later version.
  9. #
  10. # This library is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. # Library General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Library General Public
  16. # License along with this library; if not, write to the
  17. # Free Software Foundation, Inc., Franklin Street, Fifth Floor,
  18. # Boston MA  02110-1301 USA.
  19. #
  20. """Outloud voice definitions using ACSS.
  21.  
  22. This module encapsulates Outloud-specific voice definitions.  It
  23. maps device-independent ACSS voice definitions into appropriate
  24. Outloud voice parameter settings.
  25.  
  26. """
  27.  
  28. __id__ = "$Id: outloud.py 4281 2008-10-08 22:05:56Z wwalker $"
  29. __author__ = "T. V. Raman"
  30. __version__ = "$Revision: 4281 $"
  31. __date__ = "$Date: 2008-10-08 18:05:56 -0400 (Wed, 08 Oct 2008) $"
  32. __copyright__ = "Copyright (c) 2005-2008 Google Inc."
  33. __license__ = "LGPL"
  34.  
  35. import chnames
  36.  
  37. # Handling of special characters
  38. #
  39. # Emacspeak uses Tcl syntax to communicate with its speech servers.  It
  40. # embraces text in curly braces, so that at least {, }, and \ must be quoted
  41. # when sending text to speech server.  But individual speech engines have
  42. # their own special characters in addition to those of Tcl.  Outloud
  43. # perceives speech commands starting with backquote, and Emacspeak exploits
  44. # this to transmit speech settings to Outloud.  Thus we must quote `
  45. # (backquote) too.
  46.  
  47. def makeSpecialCharMap():
  48.     """Returns list of pairs mapping characters which are special for
  49.     Outloud speech server to their replacements.
  50.     """
  51.     chars = r'{\}`'
  52.     return [(ch, ' '+chnames.getCharacterName(ch)+' ') for ch in chars]
  53.  
  54.  
  55. # Speech parameters
  56.  
  57. _defined_voices = {}
  58.  
  59. # Map from ACSS dimensions to Outloud settings:
  60. def _update_map(table, key, format,  settings):
  61.     """Internal function to update acss->synth mapping."""
  62.     table[key] = {}
  63.     for setting  in  settings:
  64.         _table[key][setting[0]] = format % setting[1:]
  65.  
  66. _table = {}
  67. #family codes:
  68.  
  69. _table['family'] = {
  70.     'paul' :   " `v1 ",
  71.     'male' :   " `v1 ",
  72.     'harry' :  " `v1 `vh65 `vb50 ",
  73.     'man' :  " `v1 `vh65 `vb50 ",
  74.     'dennis' :  " `v1  `vb0 ",
  75.     'frank' :  " `v1 `vr100 ",
  76.     'betty' :  " `v7 ",
  77.     'female' :  " `v7 ",
  78.     'ursula' :  " `v2 ",
  79.     'rita' :  " `v2 `vr100 ",
  80.     'wendy' :  " `v2 `vy50 ",
  81.     'kit' :  " `v3 ",
  82. 'child' :  " `v3 "
  83. }
  84. # Average pitch for standard male voice is 65 --this is mapped to
  85. # a setting of 5.
  86. # Average pitch varies inversely with speaker head size --a child
  87. # has a small head and a higher pitched voice.
  88. # We change parameter head-size in conjunction with average pitch to
  89. # produce a more natural change on the TTS engine.
  90.  
  91. #male average pitch
  92.  
  93. _male_ap = [
  94.     (0, 0, 90),
  95.     (1, 13, 81, ),
  96.     (2, 26, 72),
  97.     (3, 39, 63),
  98.     (4, 52, 54, ),
  99.     (5, 65, 50),
  100.     (6, 74, 40),
  101.     (7, 83, 30, ),
  102.     (8, 87, 26),
  103.     (9, 92, 21)
  104.     ]
  105.  
  106. _update_map(_table, ('male', 'average-pitch'),
  107.             " `vb%s `vh%s ",  _male_ap)
  108.  
  109. # same for Paul Frank
  110. _update_map(_table, ('paul', 'average-pitch'),
  111.             " `vb%s `vh%s ",  _male_ap)
  112. _update_map(_table, ('frank', 'average-pitch'),
  113.             " `vb%s `vh%s ",  _male_ap)
  114.  
  115.  
  116. #Harry  has a big head --and a lower pitch for the middle setting
  117. _man_ap = [
  118.     (0, 0, 90),
  119.     (1, 10, 85, ),
  120.     (2, 20, 80),
  121.     (3, 30, 70),
  122.     (4, 40, 60),
  123.     (5, 50, 60),
  124.     (6, 60, 50),
  125.     (7, 70, 40, ),
  126.     (8, 80, 30),
  127.     (9, 90, 20)
  128.     ]
  129.  
  130. _update_map(_table, ('man', 'average-pitch'),
  131.             " `vb%s `vh% s", _man_ap)
  132. # same for Harry and dennis
  133. _update_map(_table, ('harry', 'average-pitch'),
  134.             " `vb%s `vh% s", _man_ap)
  135. _update_map(_table, ('dennis', 'average-pitch'),
  136.             " `vb%s `vh%s ",  _male_ap)
  137.  
  138. #defalt baseline is average pitch of 81
  139.  
  140. _female_ap = [
  141.     (0, 5, 70),
  142.     (1, 17, 66),
  143.     (2, 33, 62),
  144.     (3, 49, 58),
  145.     (4, 65, 54, ),
  146.     (5, 81, 50),
  147.     (6, 85, 55),
  148.     (7, 89, 60),
  149.     (8, 93, 65),
  150. (9, 97, 69)
  151.     ]
  152.  
  153. _update_map(_table, ('female', 'average-pitch'),
  154.             " `vb%s `vh% s",_female_ap)
  155.  
  156. # same for Betty
  157. _update_map(_table, ('betty', 'average-pitch'),
  158.             " `vb%s `vh% s",_female_ap)
  159.  
  160. _update_map(_table, ('ursula', 'average-pitch'),
  161.             " `vb%s `vh% s",_female_ap)
  162. _update_map(_table, ('rita', 'average-pitch'),
  163.             " `vb%s `vh% s",_female_ap)
  164. _update_map(_table, ('wendy', 'average-pitch'),
  165.             " `vb%s `vh% s",_female_ap)
  166.  
  167. #defalt baseline is average pitch of 81
  168.  
  169. _child_ap = [
  170.     (0, 60, 33),
  171.     (1, 65, 29),
  172.     (2, 70, 26),
  173.     (3, 75, 23),
  174.     (4, 80, 20, ),
  175.     (5, 85, 17),
  176.     (6, 90, 14),
  177.     (7, 95, 11),
  178.     (8, 97, 8),
  179.     (9, 99, 5)
  180.     ]
  181.  
  182. _update_map(_table, ('kit', 'average-pitch'),
  183.             " `vb%s `vh% s",_child_ap)
  184. _update_map(_table, ('child', 'average-pitch'),
  185.             " `vb%s `vh% s",_child_ap)
  186.  
  187.  
  188. # pitch-range for male:
  189.  
  190. #  Standard pitch range is 30 and is  mapped to
  191. # a setting of 5.
  192. # A value of 0 produces a flat monotone voice --maximum value of 100
  193. # produces a highly animated voice.
  194.  
  195. _male_pr = [
  196.     (0,0),
  197.     (1,5),
  198.     (2,15),
  199.     (3,20),
  200.     (4,25),
  201.     (5,30),
  202.     (6,47),
  203.     (7,64),
  204.     (8,81),
  205.     (9,100)
  206.     ]
  207.  
  208. _update_map(_table, ('male', 'pitch-range'),
  209.             " `vf%s  ", _male_pr)
  210.  
  211. # same for paul frank and dennis
  212. _update_map(_table, ('paul', 'pitch-range'),
  213.             " `vf%s  ", _male_pr)
  214. _update_map(_table, ('frank', 'pitch-range'),
  215.             " `vf%s  ", _male_pr)
  216. _update_map(_table, ('dennis', 'pitch-range'),
  217.             " `vf%s  ", _male_pr)
  218.  
  219.  
  220. _man_pr = [
  221.     (0, 0, ),
  222.     (1, 5, ),
  223.     (2, 15),
  224.     (3, 20),
  225.     (4, 25, ),
  226.     (5, 30, ),
  227.     (6, 47),
  228.     (7, 64),
  229.     (8, 81),
  230. (9, 100)
  231.     ]
  232.  
  233. _update_map(_table, ('man', 'pitch-range'),
  234.             " `vf%s  ", _man_pr)
  235. # same for Harry
  236. _update_map(_table, ('harry', 'pitch-range'),
  237.             " `vf%s  ", _man_pr)
  238.  
  239.  
  240. _female_pr = [
  241.     (0, 0, ),
  242.     (1, 5, ),
  243.     (2, 15),
  244.     (3, 20),
  245.     (4, 25, ),
  246.     (5, 30, ),
  247.     (6, 47),
  248.     (7, 64),
  249.     (8, 81),
  250.     (9, 100)
  251.     ]
  252.  
  253. _update_map(_table, ('female', 'pitch-range'),
  254.             " `vf%s  ", _female_pr)
  255. # same for Betty
  256. _update_map(_table, ('betty', 'pitch-range'),
  257.             " `vf%s  ", _female_pr)
  258. _update_map(_table, ('ursula', 'pitch-range'),
  259.             " `vf%s  ", _female_pr)
  260. _update_map(_table, ('rita', 'pitch-range'),
  261.             " `vf%s  ", _female_pr)
  262. _update_map(_table, ('wendy', 'pitch-range'),
  263.             " `vf%s  ", _female_pr)
  264.  
  265.  
  266. _child_pr = [
  267.     (0, 0, ),
  268.     (1, 5, ),
  269.     (2, 15),
  270.     (3, 20),
  271.     (4, 25, ),
  272.     (5, 30, ),
  273.     (6, 47),
  274.     (7, 64),
  275.     (8, 81),
  276.     (9, 100)
  277.     ]
  278.  
  279. _update_map(_table, ('kit', 'pitch-range'),
  280.             " `vf%s  ", _child_pr)
  281. _update_map(_table, ('child', 'pitch-range'),
  282.             " `vf%s  ", _child_pr)
  283.  
  284.  
  285. # Stress:
  286. # On the outloud we map stress to roughness
  287.  
  288. _male_stress = [
  289.     (0, 0),
  290.     (1, 5),
  291.     (2, 10),
  292.     (3, 15),
  293.     (4, 20, ),
  294.     (5, 25, ),
  295.     (6, 30),
  296.     (7, 35),
  297.     (8, 40),
  298.     (9, 45)
  299.     ]
  300.  
  301.  
  302. # same stress values work for other voices
  303. _update_map(_table, ('male', 'stress'),
  304.             " `vr%s  ", _male_stress)
  305. _update_map(_table, ('paul', 'stress'),
  306.             " `vr%s  ", _male_stress)
  307. _update_map(_table, ('frank', 'stress'),
  308.             " `vr%s  ", _male_stress)
  309. _update_map(_table, ('dennis', 'stress'),
  310.             " `vr%s  ", _male_stress)
  311. _update_map(_table, ('man', 'stress'),
  312.             " `vr%s  ", _male_stress)
  313. _update_map(_table, ('harry', 'stress'),
  314.             " `vr%s  ", _male_stress)
  315. _update_map(_table, ('female', 'stress'),
  316.             " `vr%s  ", _male_stress)
  317. _update_map(_table, ('betty', 'stress'),
  318.             " `vr%s  ", _male_stress)
  319. _update_map(_table, ('ursula', 'stress'),
  320.             " `vr%s  ", _male_stress)
  321. _update_map(_table, ('rita', 'stress'),
  322.             " `vr%s  ", _male_stress)
  323. _update_map(_table, ('wendy', 'stress'),
  324.             " `vr%s  ", _male_stress)
  325. _update_map(_table, ('kit', 'stress'),
  326.             " `vr%s  ", _male_stress)
  327. _update_map(_table, ('child', 'stress'),
  328.             " `vr%s  ", _male_stress)
  329.  
  330. #richness
  331.  
  332. # Smoothness and richness vary inversely.
  333. # a  maximally smooth voice produces a quieter effect
  334. # a rich voice is "bright" in contrast.
  335.  
  336. _male_richness = [
  337.     (0, 0, 60),
  338.     (1, 4, 78),
  339.     (2, 8, 80),
  340.     (3, 12, 84),
  341.     (4, 16, 88),
  342.     (5, 20, 92),
  343.     (6, 24, 93),
  344.     (7, 28, 95),
  345.     (8, 32, 97, ),
  346.     (9, 36, 100)
  347.     ]
  348.  
  349. #same settings work for other voices
  350. _update_map(_table, ('male', 'richness'),
  351.             " `vy%s  `vv%s " ,_male_richness)
  352. _update_map(_table, ('paul', 'richness'),
  353.             " `vy%s  `vv%s " ,_male_richness)
  354. _update_map(_table, ('frank', 'richness'),
  355.             " `vy%s  `vv%s " ,_male_richness)
  356. _update_map(_table, ('dennis', 'richness'),
  357.             " `vy%s  `vv%s " ,_male_richness)
  358. _update_map(_table, ('man', 'richness'),
  359.             " `vy%s  `vv%s " ,_male_richness)
  360. _update_map(_table, ('harry', 'richness'),
  361.             " `vy%s  `vv%s " , _male_richness)
  362. _update_map(_table, ('female', 'richness'),
  363.             " `vy%s  `vv%s ", _male_richness)
  364. _update_map(_table, ('betty', 'richness'),
  365.             " `vy%s  `vv%s ", _male_richness)
  366. _update_map(_table, ('ursula', 'richness'),
  367.             " `vy%s  `vv%s ", _male_richness)
  368. _update_map(_table, ('rita', 'richness'),
  369.             " `vy%s  `vv%s ", _male_richness)
  370. _update_map(_table, ('wendy', 'richness'),
  371.             " `vy%s  `vv%s ", _male_richness)
  372. _update_map(_table, ('kit', 'richness'),
  373.             " `vy%s  `vv%s ", _male_richness)
  374. _update_map(_table, ('child', 'richness'),
  375.             " `vy%s  `vv%s ", _male_richness)
  376.  
  377. # getrate is here for symmetry with other engines:
  378. # In the case of outloud, we dont need to normalize
  379.  
  380. def getrate(r):
  381.     return r
  382.  
  383. def getvoicelist():
  384.     return _table['family'].keys()
  385.  
  386. def getvoice(acss):
  387.     """Memoized function that returns  synthesizer code for
  388.     specified  ACSS setting.
  389.     Synthesizer code is a tupple of the form (open,close)
  390.     where open sets the voice, and close resets it."""
  391.  
  392.     name = acss.name()
  393.     if name in _defined_voices:
  394.         return _defined_voices[name]
  395.     _defined_voices[name] = acss2voice(acss)
  396.     return _defined_voices[name]
  397.  
  398. def acss2voice(acss):
  399.     """Return synthesizer code."""
  400.     code = ""
  401.     familyName = 'male'
  402.     if 'family' in acss:
  403.         familyName = acss['family']['name']
  404.         code += _table['family'][familyName]
  405.     if 'rate' in acss:
  406.         code += " `vs%s" % int(acss['rate'])
  407.     voice = ""
  408.     for d in ['average-pitch', 'pitch-range',
  409.               'richness', 'stress']:
  410.         if d in acss:
  411.             voice += _table[(familyName, d)][int(acss[d])]
  412.     if code or voice:
  413.         code = "%s %s" % (code, voice)
  414.     return (code, " `v1 ")
  415.